package pogvue.io;

import pogvue.analysis.AlignSeq;
import pogvue.datamodel.FeaturePair;
import pogvue.datamodel.GFF;
import pogvue.datamodel.SequenceFeature;
import pogvue.datamodel.SequenceI;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;

public class MSPFile2 extends AlignFile {
    private Vector feat;

  public MSPFile2(String inStr) {
      super(inStr);
  }

  public MSPFile2(String inFile, String type) throws IOException {
    super(inFile,type);

  }

  public Vector getFeatures() {
    return feat;
  }

  public void parse() {
      feat = new Vector();

      String line;

      try {

      String desc = "";

	  while ((line = nextLine()) != null) {

              if (line.indexOf("#") == 0) {
                  StringTokenizer str = new StringTokenizer(line," ");

                  desc = "";

		  if (str.countTokens()  > 2) {
                      str.nextToken();
                      str.nextToken();


                      while (str.hasMoreTokens()) {
                          desc = desc + str.nextToken()  + " ";
                      }
                  }
	       } else if (line.length() > 0) {

		  StringTokenizer str  = new StringTokenizer(line," ");

                  double score = Double.parseDouble(str.nextToken());
                  String tmp   = str.nextToken();
                  int strand = 1;

                  if (tmp.equals("(+1)")) {
                     strand = 1;
                  } else if (tmp.equals("(-1)"))  {
                     strand = -1;
                  } else {
                     System.out.println("Unknown strand " + tmp);
                  }

                  int qstart = Integer.parseInt(str.nextToken());
                  int qend   = Integer.parseInt(str.nextToken());
                  int tstart = Integer.parseInt(str.nextToken());
                  int tend   = Integer.parseInt(str.nextToken());

                  if (qend < qstart) {
                     int tmp2 = qstart;
                     qstart = qend;
                     qend   = tmp2;
                  }

                  String hitname = str.nextToken();
                  String hitseq  = str.nextToken();

		  SequenceFeature sf = new SequenceFeature(null,"msp",qstart,qend,desc);

		  sf.setScore(score);
		  sf.setStrand(1);
		  sf.setType2("msp");
                  sf.setAlignString(hitseq);

		  SequenceFeature hf = new SequenceFeature(null,"msp",tstart,tend,desc);

                  hf.setId(hitname);
                  hf.setScore(score);
                  hf.setStrand(strand);

                  FeaturePair fp = new FeaturePair(sf,hf);

	          feat.addElement(fp);

                  desc = "";

  	        }
	      }
      } catch (IOException e) {
	  System.out.println("Exception parsing GFFFile");
      }
      
  }

  private static String print(SequenceI[] s) {
      return print(s,72);
  }
    private static String print(SequenceI[] s, int len) {
	return print(s,len,true);
    }
    private static String print(SequenceI[] s, int len,boolean gaps) {
	StringBuffer out = new StringBuffer();
	int i = 0;
	while (i < s.length && s[i] != null) {
	    String seq;
	    if (gaps) {
		seq = s[i].getSequence();
	    } else {
		seq = AlignSeq.extractGaps(s[i].getSequence(),"-");
		seq = AlignSeq.extractGaps(seq,".");
		seq = AlignSeq.extractGaps(seq," ");
	    }

		out.append(">").append(s[i].getName()).append("/").append(s[i].getStart()).append("-").append(s[i].getEnd()).append("\n");
	    
	    int nochunks = seq.length() / len + 1;
	    
	    for (int j = 0; j < nochunks; j++) {
		int start = j*len;
		int end = start + len;
		
		if (end < seq.length()) {
            out.append(seq.substring(start, end)).append("\n");
		} else if (start < seq.length()) {
            out.append(seq.substring(start)).append("\n");
		}
	    }
	    i++;
	}
	return out.toString();
    }
    
    public String print() {
	return print(getSeqsAsArray());
    } 

    public static void main(String args[]) {
	try {
	GFFFile gff = new GFFFile(args[0],"File");

	Vector feat = gff.getFeatures();
	Hashtable fhash = new Hashtable();

	for (int i = 0; i < feat.size(); i++) {
	    SequenceFeature sf = (SequenceFeature)feat.elementAt(i);

	    String type = sf.getType();

	    if (fhash.get(type) == null) {
		GFF g = new GFF(type,"",1,2);
		fhash.put(type,g);
	    }

	    GFF g = (GFF)fhash.get(type);

	    g.addFeature(sf);
	}

	Enumeration en = fhash.keys();

	while (en.hasMoreElements()) {
	    String type = (String)en.nextElement();
	    GFF g = (GFF)fhash.get(type);

	    System.out.println("GFF " + type + " " + g.getFeatures().size());

	}
	} catch (IOException e) {
	    System.out.println("Exception " + e);
	}
    }

    public Vector getGFFFeatures() {
	Vector     feat  = getFeatures();
	Hashtable fhash  = new Hashtable();
	Vector     out   = new Vector();
	    
	for (int i = 0; i < feat.size(); i++) {
	    SequenceFeature sf = (SequenceFeature)feat.elementAt(i);
			
	    String type = sf.getType();
	    
	    if (fhash.get(type) == null) {
		GFF g = new GFF(type,"",1,2);
		fhash.put(type,g);
	    }
	    
	    GFF g = (GFF)fhash.get(type);
	    
	    g.addFeature(sf);
	}
	
	Enumeration en = fhash.keys();
	
	while (en.hasMoreElements()) {
	    String type = (String)en.nextElement();
	    GFF g = (GFF)fhash.get(type);
	    out.addElement(g);
	}
	return out;
    }

}
    




